#pragma once

#include "Reactor.hpp"
#include "Util.hpp"
#include <cerrno>
#include <string>
#include <vector>

// 一次读取的大小
#define ONCE_SIZE 64

/*
返回值 1:读取完成
       2:读取出错
       3:对端关闭链接
*/
static int RecverCore(int sock, std::string &inbuffer)
{
    while (true)
    {
        char buffer[ONCE_SIZE];
        ssize_t s = recv(sock, buffer, ONCE_SIZE, 0);
        if (s > 0)
        {
            // 读取成功
            buffer[s] = '\0';
            inbuffer += buffer;
        }
        else if (s < 0)
        {
            // 信号被中断
            if (errno == EINTR)
                continue;
            // 读完数据
            if (errno == EAGAIN || errno == EWOULDBLOCK)
            {
                return 1;
            }
            // 出错了
        }
        else // s==0
        {
        }
    }
}

int Recver(Event *evp)
{
    std::cout << "Recver been called..." << std::endl;
    // 读取
    int result = RecverCore(evp->sock, evp->inbuffer);
    // 差错处理
    if (result <= 0)
    {
        if (evp->errorer)
            // 把错误都丢给errorer函数
            evp->errorer(evp);

        return -1;
    }
    std::string sep = "H";
        // 1+2 H 33+4 H 3+5
        // 分包(解决粘包问题)
        std::vector<std::string>
            tokens;
    SplitSegment(evp->inbuffer, &tokens, "H");

    for (auto seg : tokens) // 1+2 33+4 3+5
    {
        std::string data1, data2;
        if (Deserialize(seg, &data1, &data2)) // 反序列化--提取有效参与计算或者存储信息
        {
            int x = atoi(data1.c_str());
            int y = atoi(data2.c_str());
            int z = x + y;
            std::string res = data1;
            res += "+";
            res += data2;
            res += "=";
            res += std::to_string(z);
            res += " ";

            evp->outbuffer += res; // 发送数据
        }
    }

    // 写事件,按用户的需要发送
    if (!(evp->outbuffer).empty())

        // 写打开默认就是就绪
        // 即使发送缓冲区满了,只要用户重新设置OUT事件,EPOLLOUT至少再触发一次
        evp->R->EnableRW(evp->sock, true, true);
}

/*
返回值 1:读取完成
       0:数据没发完,不能继续发
       -1:发送失败
*/
int SenderCore(int sock, std::string &outbuffer)
{
    while (true)
    {
        int total = 0; // 本轮累计发送的数据量
        const char *start = outbuffer.c_str();
        int size = outbuffer.size(); // s数据总大小
        ssize_t curr = send(sock, start + total, size - total, 0);
        if (curr > 0)
        {
            total += curr;
            if (total == size)
            {
                // 全部将数据发送完成
                outbuffer.clear();
                return 1;
            }
        }
        else
        {

            if (errno == EINTR)
                continue;
            // 数据没发完,不能继续发
            if (errno == EAGAIN || errno == EWOULDBLOCK)
            {
                outbuffer.erase(0, total);
                return 0;
            }
            return -1;
        }
    }
}

int Sender(Event *evp)
{
    std::cout << "Sender been called..." << std::endl;
    int result = SenderCore(evp->sock, evp->outbuffer);
    if (result == 1)
    {
        evp->R->EnableRW(evp->sock, true, false);
    }
    else if (result == 0)
    {
        evp->R->EnableRW(evp->sock, true, true);
    }
    else
    {
        //出错
        if (evp->errorer)
        {
            evp->errorer(evp);
        }
    }
}

int Errer(Event *evp)
{
    std::cout << "Errer been called..." << std::endl;
    evp->R->DeleteEvent(evp);
}
